﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Acme.BookStore.RBAC;
using IdentityModel;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using SC.UserCenter.Infra;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace Acme.BookStore.Logins
{
    /// <summary>
    /// 登录
    /// </summary>
    [ApiExplorerSettings(GroupName = "v2")]
    public class LoginServices : ApplicationService, ILoginServers
    {
        IRepository<User> userRepository;
        private readonly IConfiguration configuration;
        IRepository<ClientInfo> repository;
        IRepository<UserClients> loginLogRepository;


        public LoginServices(IRepository<User> userRepository, IConfiguration configuration, IRepository<ClientInfo> repository, IRepository<UserClients> loginLogRepository)
        {
            this.userRepository = userRepository;
            this.configuration = configuration;
            this.repository = repository;
            this.loginLogRepository = loginLogRepository;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginDTO"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> Login(LoginDTO loginDTO)
        {
            var list = await userRepository.GetListAsync(x=>x.IsDeleted==false);
            var A = list.Where(x => x.UserName == loginDTO.UserName);
            if (list.Where(x => x.UserName == loginDTO.UserName).Count() == 0)
            {
                return ApiResult.Fail("用户不存在");
            }
            if (list.Where(x=>x.UserIsLock == true).Count()==0)
            {
                return ApiResult.Fail("用户已锁定，请联系管理员");
            }
            if (list.Where(x=>x.UserPwd != loginDTO.UserPwd).Count()>0)
            {
                list.FirstOrDefault().UserErrorCount++;
                await userRepository.UpdateAsync(list.FirstOrDefault());
                if (list.FirstOrDefault().UserErrorCount >= 3)
                {
                    list.FirstOrDefault().UserIsLock = false;
                    await userRepository.UpdateAsync(list.FirstOrDefault());
                    return ApiResult.Fail("密码错误3次,已锁定，请联系管理员");
                }
                else
                {
                    return ApiResult.Fail("用户名与密码不匹配，请重新输入，还剩" + (3 - list.FirstOrDefault().UserErrorCount) + "次登录机会");
                }
            }
            else
            {
                list.FirstOrDefault().UserErrorCount = 0;
                list.FirstOrDefault().UserIsLock = true;
                await userRepository.UpdateAsync(list.FirstOrDefault());
                UserDTO userDTO = new UserDTO();
                userDTO.UserName = list.FirstOrDefault().UserName;
                userDTO.UserNickName = list.FirstOrDefault().UserNickName;
                userDTO.User_Phone= list.FirstOrDefault().User_Phone;
                userDTO.User_Points = list.FirstOrDefault().User_Points;
                userDTO.User_Email = list.FirstOrDefault().User_Email;
                userDTO.User_Role = list.FirstOrDefault().User_Role;
                userDTO.Token = GenerateToken(list.FirstOrDefault());
                return ApiResult.Ok(userDTO, "登录成功");
            }
            
        }


        /// <summary>
        /// 生成jwt token
        /// </summary>
        /// <param name="admin"></param>
        /// <returns></returns>
        private string GenerateToken(User admin)
        {
            IList<Claim> claims = new List<Claim> {
                                new Claim(JwtClaimTypes.Id, admin.Id.ToString()),
                                new Claim(JwtClaimTypes.Name, admin.UserName)
                            };

            //JWT密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtConfig:Bearer:SecurityKey"]));

            //算法
            var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            //过期时间
            DateTime expires = DateTime.UtcNow.AddMinutes(30);

            //Payload负载
            var token = new JwtSecurityToken(
                issuer: configuration["JwtConfig:Bearer:Issuer"],
                audience: configuration["JwtConfig:Bearer:Audience"],
                claims: claims,
                notBefore: DateTime.UtcNow,
                expires: expires,
                signingCredentials: cred
                );

            var handler = new JwtSecurityTokenHandler();

            //生成令牌
            string jwt = handler.WriteToken(token);

            return jwt;
        }



        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="loginDTO"></param>
        /// <returns></returns>
        [HttpPost("UserLogin")]
        public async Task<ApiResult> UserLogin(LoginDTO loginDTO)
        {
            var list = await loginLogRepository.GetListAsync();
            var uselist = await repository.GetListAsync();
                          
            var A = list.Where(x => x.UserName == loginDTO.UserName);
            if (list.Where(x => x.UserName == loginDTO.UserName).Count() == 0)
            {
                return ApiResult.Fail("用户不存在");
            }
            if (list.Where(x => x.IsEnabled == false).Count() == 0)
            {
                return ApiResult.Fail("用户已锁定，请联系管理员");
            }
            if (list.Where(x => x.UserPwd != loginDTO.UserPwd).Count() > 0)
            {
                list.FirstOrDefault().ErrorCount++;
                await loginLogRepository.UpdateAsync(list.FirstOrDefault());
                if (list.FirstOrDefault().ErrorCount >= 3)
                {
                    list.FirstOrDefault().IsEnabled = false;
                    await loginLogRepository.UpdateAsync(list.FirstOrDefault());
                    return ApiResult.Fail("密码错误3次,已锁定，请联系管理员");
                }
                else
                {
                    return ApiResult.Fail("用户名与密码不匹配，请重新输入，还剩" + (3 - list.FirstOrDefault().ErrorCount) + "次登录机会");
                }
            }
            else
            {
                list.FirstOrDefault().ErrorCount = 0;
                list.FirstOrDefault().IsEnabled = false;
                await loginLogRepository.UpdateAsync(list.FirstOrDefault());
                var userclent = from a in uselist
                                join b in list
                                on a.UseId equals b.Id
                                select new UserLoginDTO
                                {
                                    UserName = b.UserName,
                                    UserNickName = b.UserNickName,
                                    Id = b.Id,
                                    ClienRealcharge = a.ClienRealcharge,
                                    ClienGive = a.ClienGive,
                                    ClienIntegral = a.ClienIntegral
                                };

                return ApiResult.Ok(userclent, "登录成功");
            }
        }
    }
}
